package com.example.zqq.surfaceviewtest;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

/**
 * SurfaceView：控制surface的绘制位置
 * Surface：专门绘制的
 * SurfaceHolder：接口，访问Surface；getHolder得到这个接口。可以把它当成surface的控制器，用来操纵surface。
 * 处理它的Canvas上画的效果和动画，控制表面，大小，像素等。
 * 几个需要注意的方法：
 * // 给SurfaceView当前的持有者一个回调对象。
 * (1)、abstract void addCallback(SurfaceHolder.Callback callback);
 * <p>
 * // 锁定画布，一般在锁定后就可以通过其返回的画布对象Canvas，在其上面画图等操作了。
 * (2)、abstract Canvas lockCanvas();
 * <p>
 * // 锁定画布的某个区域进行画图等..因为画完图后，会调用下面的unlockCanvasAndPost来改变显示内容。
 * // 相对部分内存要求比较高的游戏来说，可以不用重画dirty外的其它区域的像素，可以提高速度。
 * (3)、abstract Canvas lockCanvas(Rect dirty);
 * <p>
 * // 结束锁定画图，并提交改变。
 * (4)、abstract void unlockCanvasAndPost(Canvas canvas);
 * <p>
 * <p>
 * Surfaceview变得可见时，Surface被创建，隐藏时，被销毁；
 * 若查看销毁时机，则overlord方法SurfaceCreated（。。）和SurfaceDestroyed(..)
 * Surfaceview核心提供了两个线程：UI线程和渲染线程。这里注意：
 * 1> 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用，一般来说就是应用程序主线程。
 * 渲染线程所要访问的各种变量应该作同步处理。
 * 2> 由于surface可能被销毁，它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效，
 * 所以要确保渲染线程访问的是合法有效的surface。
 * <p>
 * 需要重写的方法：
 * //在surface的大小发生改变时激发
 * （1）public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}
 * //在创建时激发，一般在这里调用画图的线程。
 * （2）public void surfaceCreated(SurfaceHolder holder){}
 * //销毁时激发，一般在这里将画图的线程停止、释放。
 * （3）public void surfaceDestroyed(SurfaceHolder holder) {}
 * <p>
 * 整个过程：
 * 继承Surfaceview 并实现 SurfaceHolder.Callback接口 ---->
 * SurfaceView.getHolder()获得SurfaceHolder对象 ---->
 * SurfaceHolder.addCallback(callback)添加回调函数 ---->
 * SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布 ---->
 * Canvas绘画 ---->
 * SurfaceHolder.unlockCanvasAndPost(Canvas canvas) 结束锁定画图，并提交改变，将图形显示。
 */
//实现了一个矩形和一个计时器
public class ViewActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(new MyView(this));
    }


    /**
     * 视图内部类
     */
    class MyView extends SurfaceView implements SurfaceHolder.Callback {

        private SurfaceHolder holder;
        private MyThread myThread;

        public MyView(Context context) {
            super(context);
            holder = this.getHolder();
            holder.addCallback(this);
            myThread = new MyThread(holder);    //创建一个绘图线程
        }

        //在创建时激发，一般在这里调用画图的线程。
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            myThread.isRun = true;
            myThread.start();
        }

        //在surface的大小发生改变时激发
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        //销毁时激发，一般在这里将画图的线程停止、释放。
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            myThread.isRun = false;
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (myThread.rect.contains((int) event.getX(), (int) event.getY())) {
                Toast.makeText(ViewActivity.this, "ssssss", Toast.LENGTH_SHORT).show();

                boolean isRun = myThread.isRun;
                Toast.makeText(ViewActivity.this, "" + isRun, Toast.LENGTH_SHORT).show();
            }
            return super.onTouchEvent(event);

        }
    }


    /**
     * 线程内部类
     */
    class MyThread extends Thread {

        private SurfaceHolder holder;
        private boolean isRun;
        private Rect rect;

        public MyThread(SurfaceHolder holder) {
            this.holder = holder;
            isRun = true;
        }

        @Override
        public void run() {
            int count = 0;
            while (isRun) {
                Canvas canvas = null;

                try {
                    synchronized (holder) {
                        //锁定画布，一般在锁定后就可以通过其返回的画布对象Canvas，在其上面画图等操作了。
                        canvas = holder.lockCanvas();
                        canvas.drawColor(Color.BLACK);      //设置画布背景颜色
                        Paint paint = new Paint();          //创建画笔
                        paint.setColor(Color.WHITE);

                        rect = new Rect(100, 150, 400, 250);
                        canvas.drawRect(rect, paint);

                        paint.setTextSize(38);
                        paint.setColor(Color.RED);
                        canvas.drawText("这是第：" + (count++) + "秒", 110, 215, paint);
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    if (canvas != null) {
                        holder.unlockCanvasAndPost(canvas);//结束锁定画图，并提交改变。
                    }
                }
            }
        }

    }


}
